import Utils from "../../../Utils";
import DestructibleFacility from "../../facility/DestructibleFacility";
import Facility from "../../facility/Facility";
import { astar } from "../../funcObj/AStar";
import { Killer } from "../../funcObj/interface/HealthPoint";
import { Location, MapLength } from "../../info/Predefine";
import GameManager from "../../manager/GameManager";
import PlayerManager from "../../manager/PlayerManager";
import DestructibleFlyer from "../DestructibleFlyer";

const { ccclass, property, requireComponent } = cc._decorator;

/**
 * 平头哥
 * 没有玩家操控时，自动出击，
 * 寻找离当前位置最近的设施周围最近的空地，
 * 寻路到空地再寻找距离空地最近的设施
 * 开始攻击 
 */
@ccclass
export default class Badger extends DestructibleFlyer {

    @property(cc.Animation)
    animation: cc.Animation = null;

    path: Location[];

    currTarget: Location;

    init(base: DestructibleFacility, target: Location): void {
        super.init(base, target);
        this.node.position = base.node.position;
        this.node.scale = 0;
        this.collider.enabled = true;
        cc.tween(this.node)
            .to(0.5, { scale: 0.9 })
            .start();
        this.dispatch(target);
        this.dispatchSuccess(0.5);
    }

    public dispatch(target: Location) {
        //如果没有传来目标位置，则随机敌人设施
        if (!target) target = this.getRandomEnemyFacilityLocation();
        if (!target) {
            this.die(null);
            return;
        }

        super.dispatch(target)
        this.currTarget = target;
        let currentLocation = GameManager.instance.getMapLocation(this.node.position);
        this.path = astar(GameManager.instance.mapArray, currentLocation, target);
        if (!!GameManager.instance.getFacilityByLocation(target)) {
            // 如果目标是一个设施，去除最后一个节点
            this.path.length -= 1;
        }
        if (this.path.length) {
            let next = this.path.shift();
            let targetPosition = GameManager.instance.getGamePosition(next);
            this.moveComp.setTarget(targetPosition, this.onPathArrive.bind(this));
            this.node.scaleX = this.node.x > targetPosition.x ? -1 : 1;
            this.animation.play("badgerMove");
        } else {
            this.onPathArrive();
        }
    }

    /**
     * 依照路径寻路
     */
    onPathArrive() {
        if (this.path.length > 0) {
            let next = this.path.shift();
            let targetPosition = GameManager.instance.getGamePosition(next);
            this.moveComp.setTarget(targetPosition, this.onPathArrive.bind(this));
            this.node.scaleX = this.node.x > targetPosition.x ? -1 : 1;
        } else {
            this.onTargetArrive();
        }
    }

    private getRandomEnemyFacilityLocation(): Location {
        let ret = null;
        let randomPlayer = Utils.getRandomChoose(PlayerManager.instance.playerComps.filter(comp => this.player !== comp && comp.allFacility.length > 0));
        if (randomPlayer) {
            let randomFac = Utils.getRandomChoose(randomPlayer.allFacility);
            ret = Utils.getRandomChoose(randomFac.locations);
        }
        return ret;
    }

    private checkAttackable(fac: Facility): boolean {
        return fac instanceof DestructibleFacility && fac.player !== this.player
    }

    /**
     * 到达离目标最近的空地后，寻找离自身最近的敌方设施
     * 如果距离小于1，直接开始攻击
     * 如果距离大于1，开始寻路最近的设施
     */
    onTargetArrive() {
        //如果周围有敌方设施
        let selfLocation = GameManager.instance.getMapLocation(this.node.position);
        let aroundLocations = [
            { locationX: Math.max(0, selfLocation.locationX - 1), locationY: selfLocation.locationY },
            { locationX: Math.min(MapLength - 1, selfLocation.locationX + 1), locationY: selfLocation.locationY },
            { locationX: selfLocation.locationX, locationY: Math.min(MapLength - 1, selfLocation.locationY + 1) },
            { locationX: selfLocation.locationX, locationY: Math.max(0, selfLocation.locationY - 1) },
        ]
        //周围可攻击的设施
        let aroundEnemyFacLocation = aroundLocations.filter(location =>
            this.checkAttackable(GameManager.instance.getFacilityByLocation(location))
        )

        if (aroundEnemyFacLocation.length > 0) {
            this.attack(Utils.getRandomChoose(aroundEnemyFacLocation));
        } else {
            //如果还有设施
            let exist = PlayerManager.instance.playerComps.find(comp => this.player !== comp && comp.allFacility.length > 0);
            if (exist) {
                this.dispatch(null);
            } else {
                this.die(null);
            }
        }
    }

    /**
     * 攻击这个位置的设施
     * @param location 
     */
    attack(location: Location) {
        let facility = GameManager.instance.getFacilityByLocation(location) as DestructibleFacility
        if (!facility) return;

        this.animation.play("badgerAttack");
        this.animation.once(cc.Animation.EventType.FINISHED, () => {
            facility = GameManager.instance.getFacilityByLocation(location) as DestructibleFacility
            if (!facility) {
                //重新寻找 
                return this.dispatch(null);
            };

            if (facility.currentHp > 0) {
                facility.reducedHp({ player: this.player, domage: this.flyerInfo.攻击力, facility: this.base, flyer: this });
            }
            if (facility.currentHp > 0) {
                //继续攻击
                this.attack(location);
            } else {
                return this.dispatch(null);
            }
        }, this);
    }

    die(killer: Killer): void {
        super.die(killer);
        this.animation.targetOff(this);
    }
}
